
package com.probiz.estore.imports.handler.basic;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.converters.BigIntegerConverter;
import org.apache.commons.beanutils.converters.BooleanConverter;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.FloatConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.LongConverter;
import org.apache.commons.beanutils.converters.ShortConverter;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.probiz.estore.common.model.product.Product;
import com.probiz.estore.imports.handler.ColumnHandler;
import com.probiz.estore.imports.model.Column;
import com.probiz.estore.imports.model.ImportModel;

/**
 * required为flase,value为空的取defaultValue,defaultValue都为空的,忽略该属性的设置
 * required为true,只取value值,空的直接忽略该条数据的导入
 * 
 * @author Administrator
 * 
 */
@SuppressWarnings("unchecked")
public class BasicHandler extends ColumnBasicHandler implements ColumnHandler {
	private Logger	logger	= Logger.getLogger(BasicHandler.class);

	/**
	 * 初始化对象
	 * 
	 * @param target
	 * @param propertiesName
	 * @throws Exception
	 */
	private void newInstanceProperties(Object target, String propertiesName)
			throws Exception {
		String properties[] = propertiesName.split("\\.");
		if (properties.length > 1) {
			for (int i = 0; i < properties.length - 1; i++) {
				String property = properties[i];
				/*
				 * 不使用BeanUtils,而使用PropertyUtils是因为Property提供类型转换功能，即发现两个JavaBean的同名属性为不同类型时，在支持的数据类型范围内进行转换，而BeanUtils不支持这个功能，但是速度会更快一些。
				 * 例如BeanUtils对形如“defaultProductSku.inventory.quantityOnhand”的格式，对于Inventory类型不能正确的转换。
				 */
				Object obj = PropertyUtils.getProperty(target, property);
				if (obj == null) {
					Method method = MethodUtils.getAccessibleMethod(target
							.getClass(), "get"
							+ StringUtils.capitalize(property), new Class[] {});
					obj = method.getReturnType().newInstance();
					PropertyUtils.setProperty(target, property, obj);
				}
				target = obj;
			}
		}
	}

	public static void main(String[] args) throws Exception {
		BasicHandler basicHandler = new BasicHandler();
		Column column = new Column();
		column.setPattern("yyyy-MM-dd");
		BeanUtilsBean beanUtils = basicHandler.getBeanUtilsBean(column);
		Product product3 = new Product();
		basicHandler.newInstanceProperties(product3,
				"defaultProductSku.inventory.quantityOnhand");
		beanUtils.setProperty(product3,
				"defaultProductSku.inventory.quantityOnhand", Integer
						.valueOf(1));
		System.out.println(beanUtils.getProperty(product3,
				"defaultProductSku.inventory.quantityOnhand"));
	}

	public void setProperty(ImportModel importModel, Column column) {
		Object target = importModel.getTarget();
		// 初始化对象时，是通过反射现实，可能会发生错误，避免出错都catch处理
		try {
			newInstanceProperties(target, column.getAttrName());
		} catch (Exception e) {
			logger.warn("处理失败数据：" + column);
			logger.error("错误信息：" + e.getMessage() + ">>>" + e);
			setDefaultResult(importModel, column);
			return;
		}
		BeanUtilsBean beanUtils = getBeanUtilsBean(column);
		// 通过反射获取对象Id时，可能会发生错误，避免出错都catch处理
		try {
			String tempId = beanUtils.getProperty(target, "id");
			if ((!column.isSupportUpdate()) && StringUtils.isNotEmpty(tempId)) {
				String tempValue = beanUtils.getProperty(target, column
						.getAttrName());
				if (!tempValue.equals(column.getValue())) {
					logger.warn("本条数据为更新，" + column.getColumnHeader()
							+ "不支持更新操作。" + column);
				}
				importModel.setResult(ImportModel.RESULT_IGNORE);
				return;
			}
		} catch (Exception e) {
			logger.warn("处理失败数据：" + column);
			logger.error("错误信息：" + e.getMessage() + ">>>" + e);
			e.printStackTrace();
		}
		// 为处理的对象设置相应值时，可能会发生错误，避免出错都catch处理，出错后设置上默认值
		try {
			beanUtils.setProperty(target, column.getAttrName(), column
					.getValue());
		} catch (Exception e1) {
			try {
				beanUtils.setProperty(target, column.getAttrName(), column
						.getDefaultValue());
			} catch (Exception e) {
				setDefaultResult(importModel, column);
				return;
			}
		}
		// 当值为空时，设置上默认值
		try {
			String tempValue = beanUtils.getProperty(target, column
					.getAttrName());
			if (StringUtils.isEmpty(tempValue)) {
				setDefaultResult(importModel, column);
			} else {
				importModel.setResult(ImportModel.RESULT_SUCCESS);
			}
		} catch (Exception e) {
			logger.warn("处理失败数据：" + column);
			logger.error("错误信息：" + e.getMessage() + ">>>" + e);
			setDefaultResult(importModel, column);
			e.printStackTrace();
		}

	}

	public BeanUtilsBean getBeanUtilsBean(final Column column) {
		ConvertUtilsBean cub = new ConvertUtilsBean();
		if (StringUtils.isNotEmpty(column.getPattern())) {
			cub.register(new Converter() {
				public Object convert(Class arg0, Object arg1) {
					SimpleDateFormat df = new SimpleDateFormat(column
							.getPattern());
					if (arg1 != null) {
						try {
							if (StringUtils.isEmpty(arg1.toString())) {
								return null;
							}
							return df.parse(arg1.toString());
						} catch (ParseException e) {
							logger.warn("处理失败数据：" + column);
							logger.error("错误信息：" + e.getMessage() + ">>>" + e);
							e.printStackTrace();
						}
					}
					return null;
				}
			}, Date.class);
		}
		cub.register(new ShortConverter(null), Short.class);
		cub.register(new IntegerConverter(null), Integer.class);
		cub.register(new DoubleConverter(null), Double.class);
		cub.register(new LongConverter(null), Long.class);
		cub.register(new FloatConverter(null), Float.class);
		cub.register(new BooleanConverter(null), Boolean.class);
		cub.register(new BigIntegerConverter(null), BigInteger.class);
		cub.register(new BigDecimalConverter(null), BigDecimal.class);
		BeanUtilsBean bean = new BeanUtilsBean(cub, new PropertyUtilsBean());
		return bean;
	}
}